<?php

namespace App\Models\Factory;

use App\Helpers\Generator\TokenGenerator;
use App\Helpers\Utils;
use App\Models\AbsModelFactory;
use App\Models\Orm\User;
use App\Models\Orm\UserBanks;
use App\Models\Orm\UserCertify;
use App\Models\Orm\UserIdentity;
use App\Models\Orm\UserProfile;
use App\Strategies\SexStrategy;

/**
 * 加密解密工厂
 * Class DecryptFactory
 * @package App\Models\Factory
 */
class DecryptFactory extends AbsModelFactory
{

    /**RSA签名函数
     * $data为待签名数据，比如URL
     * 签名用游戏方的保密私钥，必须是没有经过pkcs8转换的.结果需要用base64编码以备在URL中传输
     * return Sign 签名
     */

    public static function sign($data)
    {

        $priKey = file_get_contents('key/rsa_private_key.pem');

        //转换为openssl密钥，必须是没有经过pkcs8转换的私钥

        $res = openssl_get_privatekey($priKey);

        //调用openssl内置签名方法，生成签名$sign

        openssl_sign($data, $sign, $res);

        openssl_free_key($res);


        $sign = base64_encode($sign);

        return $sign;

    }

    /**RSA验证签名
     * $data为要验证的数据字符串
     * $sign是需要验证的签名数据，是直接从URL中取到的$_POST["sign"]型参数，函数里面会进行base64_decode的。
     * return 验签是否通过，为BOOL值
     */

    public static function verify($data, $sign)
    {

        //读取公钥文件,也就是签名方公开的公钥，用来验证这个data是否真的是签名方发出的

        $pubKey = file_get_contents('key/rsa_public_key.pem');


        $res = openssl_get_publickey($pubKey);

        //调用openssl内置方法验签，返回bool值

        $result = (bool)openssl_verify($data, base64_decode($sign), $res);


        openssl_free_key($res);

        return $result;

    }

    /**RSA公钥加密
     * $data为要加密的数据
     * $pu_key为公钥
     */

    public static function pubkeyEncrypt($source_data)
    {
        $pu_key = file_get_contents('key/rsa_public_key.pem');
        $data = "";
        $dataArray = str_split($source_data, 117);
        foreach ($dataArray as $value) {
            $encryptedTemp = "";
            openssl_public_encrypt($value, $encryptedTemp, $pu_key);//公钥加密
            $data .= base64_encode($encryptedTemp);
        }
        return $data;
    }

    /**RSA私钥解密
     * $eccryptData为要解密的数据
     * $decryptKeyq为要私钥
     */
    public static function pikeyDecrypt($eccryptData)
    {
        $priKey = file_get_contents('key/rsa_private_key.pem');
        $decrypted = "";
        $decodeStr = base64_decode($eccryptData);
        $enArray = str_split($decodeStr, 256);

        foreach ($enArray as $va) {
            openssl_private_decrypt($va, $decryptedTemp, $priKey);//私钥解密
            $decrypted .= $decryptedTemp;
        }
        return json_decode($decrypted, true);
    }


    /**
     * PHP DES 加密程式
     *
     * @param $key 密钥（8个字符）
     * @param $encrypt 要加密的明文
     * @return string 密文
     */
    public static function encrypt ($encrypt)
    {
        $key = "11111111";
        // 根據 PKCS#7 RFC 5652 Cryptographic Message Syntax (CMS) 修正 Message 加入 Padding
        $block = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_ECB);
        $pad = $block - (strlen($encrypt) % $block);
        $encrypt .= str_repeat(chr($pad), $pad);

        // 不需要設定 IV 進行加密
        $passcrypt = mcrypt_encrypt(MCRYPT_DES, $key, $encrypt, MCRYPT_MODE_ECB);
        return base64_encode($passcrypt);
    }

    /**
     * PHP DES 解密程式
     *
     * @param $key 密钥（8个字符）
     * @param $decrypt 要解密的密文
     * @return string 明文
     */
    public static function decrypt($key,$decrypt)
    {
        // 不需要設定 IV
        $str = mcrypt_decrypt(MCRYPT_DES, $key, base64_decode($decrypt), MCRYPT_MODE_ECB);

        // 根據 PKCS#7 RFC 5652 Cryptographic Message Syntax (CMS) 修正 Message 移除 Padding
        $pad = ord($str[strlen($str) - 1]);
        return substr($str, 0, strlen($str) - $pad);

    }

}
